package com.xuecheng.filesystem.service;

import com.alibaba.fastjson.JSON;
import com.xuecheng.filesystem.dao.FileSystemDao;
import com.xuecheng.framework.domain.filesystem.FileSystem;
import com.xuecheng.framework.domain.filesystem.response.FileSystemCode;
import com.xuecheng.framework.domain.filesystem.response.UploadFileResult;
import com.xuecheng.framework.exception.ExceptionCast;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import com.xuecheng.framework.model.response.ResponseResult;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Map;
@Service
public class FileSystemService {
    //连接tracker的地址
    @Value("${xuecheng.fastdfs.tracker_servers}")
    String tracker_servers;
    //连接超时时间
    @Value("${xuecheng.fastdfs.connect_timeout_in_seconds}")
    int connect_timeout_in_seconds;
    //网络超时时间
    @Value("${xuecheng.fastdfs.network_timeout_in_seconds}")
    int network_timeout_in_seconds;
    //设置编码格式
    @Value("${xuecheng.fastdfs.charset}")
    String charset;

    @Autowired private FileSystemDao fileSystemDao;

    public UploadFileResult uoload(MultipartFile multipartFile, String businesskey,String filetag ,String metadata){

        //存入FastDFS
        String fileId=this.fdfs_uplad(multipartFile);
        if(fileId == null){
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
        }
        //信息存入MongoDB
        FileSystem fileSystem = new FileSystem();
        fileSystem.setFileId(fileId);
        fileSystem.setFilePath(fileId);
        fileSystem.setFileName(multipartFile.getOriginalFilename());
        fileSystem.setBusinesskey(businesskey);
        fileSystem.setFiletag(filetag);
        fileSystem.setFileType(multipartFile.getContentType());
        if (metadata!=null){
            try{
                Map map = JSON.parseObject(metadata,Map.class);
                fileSystem.setMetadata(map);
            }catch(Exception e){
                ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_METAERROR);
            }

        }
        fileSystemDao.save(fileSystem);
        return new UploadFileResult(CommonCode.SUCCESS,fileSystem);
    }

    //上传文件到FastDTFS
    public String fdfs_uplad(MultipartFile multipartFile){
        //判断文件是否为空
        if(multipartFile==null){
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_FILEISNULL);
        }
        try {
            //加载fdfs的配置
            initFdfsConfig();
            //创建tracker client
            TrackerClient trackerClient = new TrackerClient();
            //获取trackerServer
            TrackerServer trackerServer = trackerClient.getConnection();
            //获取storage
            StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
            //创建storage client
            StorageClient1 storageClient1 = new StorageClient1(trackerServer,storeStorage);
            //得到文件的字节流
            byte[] bytes = multipartFile.getBytes();
            //得到文件的原始名称
            String originalFilename = multipartFile.getOriginalFilename();
            //得到文件的扩展名
            String ext=originalFilename.substring(originalFilename.lastIndexOf(".")+1);



            //上传文件,得到返回的ID
            String fileId=storageClient1.upload_file1(bytes,ext,null);
            return  fileId;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
            ExceptionCast.cast(FileSystemCode.FS_CONNECT_FDFS_ERROR);
        }
        return null;
    }


    //删除文件，先删除FastDFS,再删除MongoDB
    public ResponseResult delete(String fileId){
        //判断Id是否为空
        if(fileId==null){
            new ResponseResult(FileSystemCode.FS_UPLOADFILE_BUSINESSISNULL);
        }
        //删除FastDFS中的文件
        int success=this.fdfs_delete(fileId);
        if(success!=0){
            ExceptionCast.cast(FileSystemCode.FS_DELETEFILE_SERVERFAIL);
        }
        //删除MongoDB中的记录
        fileSystemDao.deleteById(fileId);
        return  new ResponseResult(CommonCode.SUCCESS);
    }

    //删除FastDTFS中的文件
    public int fdfs_delete(String fileId){
        //判断文件是否为空
        try {
            //加载fdfs的配置
            initFdfsConfig();
            //创建tracker client
            TrackerClient trackerClient = new TrackerClient();
            //获取trackerServer
            TrackerServer trackerServer = trackerClient.getConnection();
            //获取storage
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            //创建storage client
            StorageClient1 storageClient1 = new StorageClient1(trackerServer,storageServer);

            //删除文件,得到返回的状态值，返回的0表示成功，2表示没有此文件
            int success=storageClient1.delete_file1(fileId);
            return  success;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
            ExceptionCast.cast(FileSystemCode.FS_CONNECT_FDFS_ERROR);
        }
        return -1;
    }


    //查询文件
    public QueryResponseResult fandAll(int page,int size,FileSystem fileSystem){
        if(page<=0){
            page=1;
        }
        page--;
        if (size<=0){
            size=10;
        }
        //创建查询的条件
        Pageable pageable = PageRequest.of(page,size);

        ExampleMatcher exampleMatcher= ExampleMatcher.matching();
        exampleMatcher = exampleMatcher.withMatcher("fileId",ExampleMatcher.GenericPropertyMatchers.contains());
        exampleMatcher = exampleMatcher.withMatcher("fileName",ExampleMatcher.GenericPropertyMatchers.contains());
        Example example = Example.of(fileSystem,exampleMatcher);

        //查询文件
        Page<FileSystem> data = fileSystemDao.findAll(example,pageable);

        QueryResult queryResult = new QueryResult();
        queryResult.setList(data.getContent());
        queryResult.setTotal(data.getTotalElements());
        queryResult.setTotalPage(data.getTotalPages());
        return new  QueryResponseResult(CommonCode.SUCCESS,queryResult);
    }



    //初始化FastDFS环境
    //加载fdfs的配置
    private void initFdfsConfig(){
        try {
            ClientGlobal.initByTrackers(tracker_servers);
            ClientGlobal.setG_connect_timeout(connect_timeout_in_seconds);
            ClientGlobal.setG_network_timeout(network_timeout_in_seconds);
            ClientGlobal.setG_charset(charset);
        } catch (Exception e) {
            e.printStackTrace();
            // 初始化文件系统出错
            ExceptionCast.cast(FileSystemCode.FS_INITFDFSERROR);
        }
    }


}
